-- 状态机

-- 模块定义
local M = 
{
    _base_class = require "states.BaseState",
    _class_name = "states.StateMachine",
};
setmetatable (M, {__index = _G;});
_ENV = M;

-- 引用模块
local Tools = require "tools.CommonTools";
local Map = require "collections.Map"

-- 方法定义
operation_table = Tools.CreateOperationTable (_base_class);

-- 添加状态。状态机中需要跳转的状态应该在状态机启动之前全部添加进去。
function operation_table.AddState (self, state, is_default)
    self._states:Add (state:GetName (), state);
    state:SetFsm (self);
    if (is_default) then
        self._current_state = state;
    end;
end;

-- 启动状态机
function operation_table.Start (self)
    if (self._current_state == nil) then
        error ("state_machine: start failed because no default state specified.");
    end;
    self:_get_base_method ("Start") (self);
    self._current_state:Start ();
end;

-- 停止状态机
function operation_table.Stop (self)
    if (self._current_state == nil) then
        error ("state_machine: stop failed because no current state specified.");
    end;
    self._current_state:Stop ();
    self:_get_base_method ("Stop") (self);
end;

-- 更新状态机
function operation_table.Update (self, current_time, delta_time)
    if (self:_IsRunning ()) then
        if (self._current_state ~= nil) then
            self._current_state:Update (current_time, delta_time);
        else
            error ("state_machine: update failed because no current state specified.");
        end;
    end;
end;

-- 切换状态
function operation_table.ChangeToState (self, state_name)
    if (self:_IsRunning ()) then
        self._current_state:Stop ();
        self._current_state = self._states:GetItem (state_name);
        self._current_state:Start ();
    end;
end;

-- 构造方法
function NewStateMachine (entity)
    local instance = _base_class.NewBaseState (entity);
    Tools.PrepareInstance (M, instance);

    -- 私有成员
    instance._current_state = nil;
    instance._states = Map.NewMap ();

    return instance;
end;

return M;
